﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.IO.Compression;
using System.Web.UI;
using System.Web.UI.WebControls;
using CoolERP_Entities;
using CoolERP_BLL;
using System.Text.RegularExpressions;
using System.Collections;
using CoolERP_Common;

namespace CoolERP_Web
{
    [PermissionCheck()]
    public class BasePage : System.Web.UI.Page
    {
        protected string SessionKey = "CurrentUser";  

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // 分析是否有SQL注入式攻击代码
            AnalysicSqlInjection();

            // 权限判断处理
            foreach (object obj in this.GetType().GetCustomAttributes(typeof(PermissionCheckAttribute), true))
            {
                PermissionCheckAttribute permission = obj as PermissionCheckAttribute;
                if (permission.isCheck)
                    DoCheckPermission();
            }
        }

        protected virtual void btnReset_Click(object sender, EventArgs e)
        {
            string scriptString = string.Format("location.href='{0}';", this.Request.RawUrl);
            AjaxWebJavaScript(scriptString);
        }

        #region======SQL注入式攻击代码分析======
        /// <summary>
        /// 分析是否有SQL注入式攻击代码
        /// </summary>
        public void AnalysicSqlInjection()
        {
            try
            {
                string getkeys = "";
                string errerPage = "/Error.aspx?code=sql_injection";
                if (System.Web.HttpContext.Current.Request.QueryString != null)
                {
                    for (int i = 0; i < System.Web.HttpContext.Current.Request.QueryString.Count; i++)
                    {
                        getkeys = System.Web.HttpContext.Current.Request.QueryString.Keys[i];
                        if (!CheckSqlInjection(System.Web.HttpContext.Current.Request.QueryString[getkeys]))
                        {

                            string msg = string.Format("Nickname={0};sql_url={1}", "", this.Request.RawUrl);
                            ApplicationException ex = new ApplicationException(msg);
                            //Utility.LogError("sql_injection", ex);
                            System.Web.HttpContext.Current.Response.Redirect(errerPage);
                            System.Web.HttpContext.Current.Response.End();
                        }
                    }
                }
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// 分析用户请求是否正常
        /// </summary>
        /// <param name="inputString">传入用户提交数据</param>
        /// <returns>返回是否含有SQL注入式攻击代码</returns>
        protected bool CheckSqlInjection(string inputString)
        {
            inputString = inputString.ToLower();
            bool isSuccess = true;
            try
            {
                if (inputString != "")
                {
                    const string SQL_injdata = @"'|;|\s+or\s+|\s+and\s+|^\s*union\s+|^\s*exec\s+|^\s*insert\s+|^\s*select\s+|^\s*delete\s+|^\s*update\s+|^\s*from\s+|^\s*declare\s+|master\.|^\s*xp_|^\s*count\(|^\s*mid\(|^\s*truncate\s+|^\s*char\(";
                    System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(SQL_injdata, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    isSuccess = !regex.IsMatch(inputString);
                }
            }
            catch
            {
                isSuccess = false;
            }
            return isSuccess;
        }
        #endregion

        /// <summary>
        /// 权限判断处理
        /// </summary>
        private void DoCheckPermission()
        {
            CacheManager cache = new CacheManager();
            if (this.currentUser.IsAnonymous || cache.Exist(Utility.UrlCacheKey) == false)
            {
                string script = "top.location.href='" + this.LoginUrl + "';";
                this.AjaxWebJavaScript(script);
            }
            else
            {
                string Code = string.Empty;
                string currentUrl = this.Request.RawUrl.ToLower().Substring(this.Request.RawUrl.ToLower().LastIndexOf('/') + 1);
                if (cache.Exist(Utility.UrlCacheKey))
                {
                    //从缓存的页面中（url/code）匹配url，获取code
                    Hashtable ht = (Hashtable)cache.Get(Utility.UrlCacheKey);
                    foreach (var item in ht.Keys)
                    {
                        string url = item.ToString().ToLower();
                        if (url.Contains('?')) // url中包含？符号的
                        {
                            if (url == currentUrl)
                            {
                                Code = ht[item].ToString();
                                break;
                            }
                        }
                        else
                        {
                            string urlMatch = "^" + url + "(.{0,})$";
                            Regex re = new Regex(urlMatch, RegexOptions.IgnoreCase);
                            if (re.IsMatch(currentUrl))
                            {
                                Code = ht[item].ToString();
                                break;
                            }
                        }
                    }
                }
                //根据缓存的权限code，判断是否有权限访问页面
                if (!this.currentUser.PermissionCodes.Contains(Code))
                    Response.Redirect(string.Format("{0}NotPermission.aspx", AppPath));
            }
        }

        /// <summary>
        /// 应用程序路径 如："/" 或 ""(域级)
        /// </summary>
        public string AppPath
        {
            get { return this.ResolveUrl("~/"); }
        }

        /// <summary>
        /// 登录页面
        /// </summary>
        public string LoginUrl
        {
            get
            {
                return string.Format("{0}Login.aspx", this.AppPath);
            }
        }

        public object GetUrlParam(string RequestKey)
        {
            object key = null;
            try
            {
                if (RequestKey != string.Empty)
                {
                    if (this.ViewState[RequestKey] == null)
                    {
                        if (this.Request.QueryString[RequestKey] != null)
                            this.ViewState[RequestKey] = this.Request.QueryString[RequestKey].ToString();
                        else
                            this.ViewState[RequestKey] = null;
                    }
                    key = this.ViewState[RequestKey];
                }
            }
            catch
            {
                return null;
            }
            return key;
        }

        /// <summary>
        /// 当前用户
        /// </summary>
        public CurrentUser currentUser
        {
            get
            {
                if (this.Session[SessionKey] == null)
                {
                    CurrentUser user = new CurrentUser();
                    user.UserID = Guid.Empty;
                    Random r = new Random();
                    string name = "游客" + r.Next(0, 999).ToString();
                    user.UserName = name;
                    user.IsAnonymous = true;
                    user.PermissionCodes = null;
                    this.Session[SessionKey] = user;
                }
                return (CurrentUser)this.Session[SessionKey];
            }
            set { this.Session[SessionKey] = value; }
        }

        /// <summary>
        /// 刷新页面
        /// </summary>
        public void Referer()
        {
            string scriptString = string.Format("location.href='{0}';", Request.ServerVariables["HTTP_REFERER"]);
            AjaxWebJavaScript(scriptString);
        }

        #region======对话框事件======
        /// <summary>
        /// 函数作用：在server端生成用于客户端alert信息的Messagebox框
        /// </summary>
        /// <param name="strMessage">需要alert的信息</param>
        public void ShowMessage(string strMessage)
        {
            if (strMessage != "")
                ShowMessage(strMessage, string.Empty);
        }

        /// <summary>
        /// 函数作用：在server端生成用于客户端alert信息的Messagebox框
        /// </summary>
        /// <param name="strMessage">需要alert的信息</param>
        /// <param name="url">需要跳转的url</param>
        public void ShowMessage(string strMessage, string url)
        {
            string script = string.Format("alert('{0}');", ToJavascriptAlartableString(strMessage));
            if (url != string.Empty)
                script += string.Format("location.href='{0}';", url);

            AjaxWebJavaScript(script);
        }

        /// <summary>
        /// 函数作用：在server端生成用于客户端alert信息的Messagebox框，同时刷新当前页面
        /// </summary>
        /// <param name="strMessage">需要alert的信息</param>
        public void ShowMsg(string strMessage)
        {
            if (strMessage != "")
                ShowMsg(strMessage, string.Empty);
        }

        /// <summary>
        /// 函数作用：在server端生成用于客户端alert信息的Messagebox框，同时刷新当前页面
        /// </summary>
        /// <param name="strMessage">需要alert的信息</param>
        /// <param name="url">需要跳转的url</param>
        public void ShowMsg(string strMessage, string url)
        {
            string script = string.Format("alert('{0}');", ToJavascriptAlartableString(strMessage));
            if (url != string.Empty)
                script += string.Format("location.href='{0}';", url);
            else
                script += string.Format("location.href='{0}';", Request.ServerVariables["HTTP_REFERER"]);
            Response.Write(string.Format("<script language=javascript>{0}</script>", script));
        }

        /// <summary>
        /// 函数作用：执行JS代码
        /// </summary>
        /// <param name="scriptString">要执行的JS</param>
        public void AjaxWebJavaScript(string scriptString)
        {
            System.Web.UI.ScriptManager.RegisterStartupScript(this.Page, typeof(string), Guid.NewGuid().ToString(), scriptString, true);
        }

        /// <summary>
        /// 函数作用：把指定的字符串sMsgInfo转化成javascript能够alert的字符串。
        /// </summary>
        /// <param name="sMsgInfo">需要转换的字符串</param>
        protected string ToJavascriptAlartableString(string sMsgInfo)
        {
            return sMsgInfo.Replace("\'", "\\'").Replace("\"", "\\\"").Replace("</", "<\\/");
        }
        #endregion

        #region======压缩ViewState======
        protected override void SavePageStateToPersistenceMedium(object pageViewState)
        {
            LosFormatter losformatter = new LosFormatter();
            StringWriter sw = new StringWriter();
            losformatter.Serialize(sw, pageViewState);
            string viewStateString = sw.ToString();
            byte[] b = Convert.FromBase64String(viewStateString);
            b = ViewStateCompression.Compress(b);
            // ----ClientScript.RegisterHiddenField( "__ZIPSTATE", Convert.ToBase64String( b ) );
            //
            // 兼容ASP.NET AJAX 的ViewState压缩
            ScriptManager.RegisterHiddenField(this, "__ZIPSTATE", Convert.ToBase64String(b));
        }

        // 序列化ViewState
        protected override object LoadPageStateFromPersistenceMedium()
        {
            string custState = Request.Form["__ZIPSTATE"];
            byte[] b = Convert.FromBase64String(custState);
            b = ViewStateCompression.Decompress(b);
            LosFormatter losformatter = new LosFormatter();
            return losformatter.Deserialize(Convert.ToBase64String(b));
        }
        #endregion

        #region======绑定基础数据======
        /// <summary>
        /// 供应商
        /// </summary>
        public void BindGYS(ListControl control, string defString)
        {
            control.Items.Clear();
            using (ZL_GYSBLL zBLL = new ZL_GYSBLL())
            {
                control.DataSource = zBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "ID";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 物料类型
        /// </summary>
        public void BindWLLX(ListControl control, string defString)
        {
            control.Items.Clear();
            using (CS_WLLXBLL cBLL = new CS_WLLXBLL())
            {
                control.DataSource = cBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 产品类型
        /// </summary>
        public void BindCPLX(ListControl control, string defString)
        {
            using (CS_CPLXBLL cBLL = new CS_CPLXBLL())
            {
                control.DataSource = cBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
                if (!string.IsNullOrEmpty(defString))
                    control.Items.Insert(0, new ListItem(defString, ""));
            }
        }

        /// <summary>
        /// 产品线
        /// </summary>
        public void BindCPX(ListControl control, string defString)
        {
            control.Items.Clear();
            using (CS_CPXBLL cBLL = new CS_CPXBLL())
            {
                control.DataSource = cBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 产品核心词
        /// </summary>
        public void BindCPHXC(ListControl control, string cpxbh, string defString)
        {
            control.Items.Clear();
            using (CS_CPMCBLL cBLL = new CS_CPMCBLL())
            {
                List<CS_CPMC> items = new List<CS_CPMC>();
                if (string.IsNullOrEmpty(cpxbh))
                    items = cBLL.GetAll();
                else
                    items = cBLL.GetList(t => t.CPXBH == cpxbh);
                control.DataSource = items;
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 产品系列
        /// </summary>
        public void BindCPXL(ListControl control, string cpxbh, string defString)
        {
            control.Items.Clear();
            using (CS_CPXLBLL cBLL = new CS_CPXLBLL())
            {
                List<CS_CPXL> items = new List<CS_CPXL>();
                if (string.IsNullOrEmpty(cpxbh))
                    items = cBLL.GetAll();
                else
                    items = cBLL.GetList(t => t.CPXBH == cpxbh);
                control.DataSource = items;
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 产品型号
        /// </summary>
        public void BindCPXH(ListControl control, string cpxbh, string hxcbh, string defString)
        {
            control.Items.Clear();
            using (CS_CPXHBLL cBLL = new CS_CPXHBLL())
            {
                List<CS_CPXH> items = new List<CS_CPXH>();
                if (string.IsNullOrEmpty(cpxbh) && string.IsNullOrEmpty(hxcbh))
                    items = cBLL.GetAll();
                else
                {
                    if (!string.IsNullOrEmpty(cpxbh) && !string.IsNullOrEmpty(hxcbh))
                        items = cBLL.GetList(t => t.CPXBH == cpxbh && t.CPMCBH == hxcbh);
                    else if(!string.IsNullOrEmpty(cpxbh) && string.IsNullOrEmpty(hxcbh))
                        items = cBLL.GetList(t => t.CPXBH == cpxbh);
                    else if (string.IsNullOrEmpty(cpxbh) && !string.IsNullOrEmpty(hxcbh))
                        items = cBLL.GetList(t => t.CPMCBH == hxcbh);
                }
                control.DataSource = items;
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 产品颜色
        /// </summary>
        public void BindCPYS(ListControl control, string lxbh, string defString)
        {
            control.Items.Clear();
            using (CS_YSBLL cBLL = new CS_YSBLL())
            {
                List<CS_YS> items = new List<CS_YS>();
                if (string.IsNullOrEmpty(lxbh))
                    items = cBLL.GetAll();
                else
                    items = cBLL.GetList(t => t.YSLXBH == lxbh);
                control.DataSource = items;
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 产品颜色类型
        /// </summary>
        public void BindCPYSLX(ListControl control, string defString)
        {
            control.Items.Clear();
            using (CS_YSLXBLL cBLL = new CS_YSLXBLL())
            {
                List<CS_YSLX> items = cBLL.GetAll();
                control.DataSource = cBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 部门
        /// </summary>
        public void BindDepartment(ListControl control, string defString)
        {
            int DepDegree = 0;//记录分类层级
            using (DepartmentsBLL dBLL = new DepartmentsBLL())
            {
                List<Departments> tempList = new List<Departments>();
                List<Departments> lsDep = dBLL.GetAll();
                control.DataSource = GetDepDegree(tempList, ref lsDep, null, ref DepDegree);
                control.DataTextField = "Name";
                control.DataValueField = "ID";
                control.DataBind();
                if(!string.IsNullOrEmpty(defString))
                    control.Items.Insert(0, new ListItem(defString, ""));
            }
        }

        /// <summary>
        /// 部门
        /// </summary>
        public void BindDepartment(ListControl control, EnumDepartment _enum, string defString)
        {
            using (DepartmentsBLL dBLL = new DepartmentsBLL())
            {
                List<ValueTextItem> dataList = new List<ValueTextItem>();
                string key = string.Format("Department_{0}", _enum);
                List<Departments> tempList = dBLL.GetAll();
                foreach (var item in dBLL.GetList(t => t.Key == key))
                {
                    string name = string.Empty;
                    string[] ids = item.Path.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var id in ids)
                    {
                        Departments entity = tempList.FirstOrDefault(t => t.Id == new Guid(id));
                        name += "->" + entity.Name;
                    }
                    if (!string.IsNullOrEmpty(name))
                        name = name.Substring(2);
                    dataList.Add(new ValueTextItem(item.Id, name));
                }
                control.DataSource = dataList;
                control.DataTextField = "Text";
                control.DataValueField = "Value";
                control.DataBind();
                if (!string.IsNullOrEmpty(defString))
                    control.Items.Insert(0, new ListItem(defString, ""));
            }
        }

        private List<Departments> GetDepDegree(List<Departments> tempList, ref List<Departments> allList, Guid? pid, ref int DepDegree)
        {
            foreach (var item in allList.Where(t => t.ParentId == pid))
            {
                if (DepDegree > 0)
                    item.Name = Server.HtmlDecode(Utility.GenSpace(DepDegree * 4)) + "├ " + item.Name;
                tempList.Add(item);
                DepDegree++;
                GetDepDegree(tempList, ref allList, item.Id, ref DepDegree);
            }
            DepDegree--;
            return tempList;
        }

        /// <summary>
        /// 根据部门ID返回职员
        /// </summary>
        /// <param name="depId"></param>
        /// <param name="control"></param>
        /// <param name="defString"></param>
        public void BindStaff(string depId, ListControl control, string defString)
        {
            control.Items.Clear();
            if (!string.IsNullOrEmpty(depId))
            {
                using (UserInDepartmentsBLL uBLL = new UserInDepartmentsBLL())
                {
                    List<Users> itemList = uBLL.GetUsersByDepartmentId(Guid.Parse(depId)).Select(t => t.Users).ToList();
                    control.DataSource = itemList;
                    control.DataTextField = "Name";
                    control.DataValueField = "Id";
                    control.DataBind();
                }
            }
            control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 仓库
        /// </summary>
        public void BindCK(ListControl control, string defString)
        {
            control.Items.Clear();
            using (ZL_CKBLL zBLL = new ZL_CKBLL())
            {
                control.DataSource = zBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "ID";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 基本单位
        /// </summary>
        /// <param name="control"></param>
        /// <param name="sz">编号开头的数字</param>
        public void BindJBDW(ListControl control, string sz, string defString)
        {
            control.Items.Clear();
            using (CS_JBDWBLL jBLL = new CS_JBDWBLL())
            {
                List<CS_JBDW> items = new List<CS_JBDW>();
                if (string.IsNullOrEmpty(sz))
                    items = jBLL.GetAll();
                else
                    items = jBLL.GetList(t => t.BH.StartsWith(sz));
                control.DataSource = items;
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }

        /// <summary>
        /// 进出仓原因
        /// </summary>
        public void BindJCCYY(ListControl control, string defString)
        {
            control.Items.Clear();
            using (CS_JCCYYBLL jBLL = new CS_JCCYYBLL())
            {
                control.DataSource = jBLL.GetAll();
                control.DataTextField = "MC";
                control.DataValueField = "BH";
                control.DataBind();
            }
            if (!string.IsNullOrEmpty(defString))
                control.Items.Insert(0, new ListItem(defString, ""));
        }
        #endregion        
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class PermissionCheckAttribute : Attribute
    {
        public bool isCheck { get; set; }
        public PermissionCheckAttribute()
        {            
            isCheck = Utility.IsCheckPermission();
        }
        public PermissionCheckAttribute(bool _isCheck)
        {
            isCheck = _isCheck;
        }
    }

    /// <summary>
    /// 压缩ViewState
    /// </summary>
    public class ViewStateCompression
    {
        public ViewStateCompression()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        // 压缩
        public static byte[] Compress(byte[] data)
        {
            MemoryStream output = new MemoryStream();
            GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
            gzip.Write(data, 0, data.Length);
            gzip.Close();
            return output.ToArray();
        }

        // 解压缩
        public static byte[] Decompress(byte[] data)
        {
            MemoryStream input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0;
            GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
            MemoryStream output = new MemoryStream();
            byte[] buff = new byte[64];
            int read = -1;
            read = gzip.Read(buff, 0, buff.Length);
            while (read > 0)
            {
                output.Write(buff, 0, read);
                read = gzip.Read(buff, 0, buff.Length);
            }
            gzip.Close();
            return output.ToArray();
        }
    }
}